//  -----------------------------------------------------------------------------------------------//
//   This file is part of SvnExternalUpdater                                                               //
//   Copyright (C)2008 Romain Verdier ( romain@codingly.com )                                      //
//                                                                                                 //
//   This program is free software; you can redistribute it and/or modify it under the terms       //
//   of the GNU General Public License as published by the Free Software Foundation; either        //
//   version 2 of the License, or (at your option) any later version. This program is distributed  //
//   in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied        //
//   warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public  //
//   License for more details.                                                                     //
//                                                                                                 //
//   You should have received a copy of the GNU General Public License along with this program; if //
//   not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. or  //
//   see http://www.fsf.org/licensing/licenses/gpl.html                                            //
//  -----------------------------------------------------------------------------------------------//
using System;
using System.Collections.Generic;
using Codingly.SvnExternalUpdater.Core.EventHandlers;
using Codingly.SvnExternalUpdater.Core.Model;
using Codingly.SvnExternalUpdater.Core.Services;
using Codingly.SvnExternalUpdater.Mvp;
using Codingly.SvnExternalUpdater.Views;

namespace Codingly.SvnExternalUpdater.Presenters
{
	public class ProjectPresenter : AbstractPresenter<IProjectView, ProjectPresenter>
	{
		private readonly IFileSystemService fileSystemService;
		private readonly IPresenterProvider presenterProvider;
		private readonly Dictionary<IExternal, ExternalPresenter> presenters = new Dictionary<IExternal, ExternalPresenter>();
		private IProject project;
		private string targetPlaceHolderKey;

		public ProjectPresenter(IPresenterProvider presenterProvider, IFileSystemService fileSystemService)
		{
			this.presenterProvider = presenterProvider;
			this.fileSystemService = fileSystemService;
		}

		public IProject Project
		{
			get { return this.project; }
			set { this.project = value; }
		}

		public string TargetPlaceHolderKey
		{
			get { return this.targetPlaceHolderKey; }
			set { this.targetPlaceHolderKey = value; }
		}

		public void ExplorePath()
		{
			this.fileSystemService.ExplorePath(this.project.Path);
		}

		public void Start(IProject project, string targetPlaceHolderKey)
		{
			this.project = project;
			this.project.Changed += project_Changed;
			this.project.ExternalAdded += project_ExternalAdded;
			this.project.ExternalRemoved += project_ExternalRemoved;
			this.targetPlaceHolderKey = targetPlaceHolderKey;
			this.view.PlaceHolderKey = this.project.Path;
			this.view.Append(targetPlaceHolderKey);
			foreach (IExternal external in this.project.Externals)
			{
				AddExternal(external);
			}
			UpdateView();
		}

		public void Stop()
		{
			this.project.Changed -= project_Changed;
			this.project.ExternalAdded -= project_ExternalAdded;
			this.project.ExternalRemoved -= project_ExternalRemoved;
			this.view.Remove(this.targetPlaceHolderKey);
		}

		private void AddExternal(IExternal external)
		{
			if (!this.presenters.ContainsKey(external))
			{
				var presenter = this.presenterProvider.Get<ExternalPresenter>();
				presenter.Start(external, this.view.PlaceHolderKey);
				this.presenters.Add(external, presenter);
			}
		}

		private void UpdateView()
		{
			this.view.ProjectName = this.project.Name;
			this.view.ProjectPath = this.project.Path;
			this.view.ProjectUrl = this.project.Url.ToString();
			this.view.IsUpToDate = this.project.IsUpToDate;
		}

		private void project_Changed(object sender, ProjectEventArgs args)
		{
			UpdateView();
		}

		private void project_ExternalAdded(object sender, ExternalEventArgs args)
		{
			AddExternal(args.External);
		}

		private void project_ExternalRemoved(object sender, ExternalEventArgs args)
		{
			ExternalPresenter presenter;
			if (this.presenters.TryGetValue(args.External, out presenter))
			{
				presenter.Stop();
				this.presenters.Remove(args.External);
			}
		}

	    public void Update()
	    {
	        throw new NotImplementedException();
	    }
	}
}